package util

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"strings"
)

func RunCmd(dir, name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	return cmd.Run()
}

func RunCmdWithResult(dir, name string, args ...string) (string, error) {
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	err := cmd.Run()
	if err != nil {
		return "", err
	}
	cmd.Stdout = os.Stdout
	output, e := cmd.Output()
	if e != nil {
		log.Fatalf("get cmd output error: %s", e.Error())
	}
	return string(output), nil
}

func RunWithOutput(dir, name string, args ...string) error {
	cmd := exec.Command(name, args...)
	cmd.Dir = dir
	log.Printf("exec cmd: %s", strings.Join(cmd.Args, " "))

	stdout, err := cmd.StdoutPipe()

	if err != nil {
		return err
	}

	err = cmd.Start()
	if err != nil {
		return err
	}

	reader := bufio.NewReader(stdout)

	//实时循环读取输出流中的一行内容
	for {
		line, err2 := reader.ReadString('\n')
		if err2 != nil || io.EOF == err2 {
			break
		}
		fmt.Print(line)
	}

	return cmd.Wait()
}

func IsExists(path string, flag string) bool {
	fi, err := os.Stat(path)
	if err != nil {
		return os.IsExist(err)
	}

	switch flag {
	case "file":
		return !fi.IsDir()
	case "dir":
		return fi.IsDir()
	}
	return false
}

func CopyFile(srcPath, dstPath string) error {
	src, err := os.Open(srcPath)
	if err != nil {
		return err
	}
	defer src.Close()
	dst, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE, 755)
	if err != nil {
		return err
	}
	defer dst.Close()
	_, err = io.Copy(dst, src)
	return err

}

func RunShell(detail bool, name string, args ...string) error {
	if detail {
		return RunWithOutput("", name, args...)
	} else {
		return RunCmd("", name, args...)
	}
}

func RunShellWithDir(detail bool, dir, name string, args ...string) error {
	if detail {
		return RunWithOutput(dir, name, args...)
	} else {
		return RunCmd(dir, name, args...)
	}
}
